using System;
using System.Collections.Generic;
using COC.CComponent;
using COC.CEvent;
using COC.Character;
using COC.Character.Extra;
using COC.Constant;
using COC.Debug;
using COC.Service;
using UnityEngine;
using System.Collections;
using COC.UIAction;
using Random = UnityEngine.Random;

namespace COC
{
    public class SceneManager
    {

        private static SceneManager instance;
        private static CacheService _cacheService;
        private GameObject _scene;
        private static GameObject _root;
        private static Queue<CharacterDataModel> list = new Queue<CharacterDataModel>();
        private static bool isInput;
        static Vector3 currMousePos;
        public SceneManager()
        {
            _scene = new GameObject(CommonConstants.SCENE_MANAGER_NAME);
            _scene.tag = CommonConstants.SCENE_MANAGER_TAG;
            _scene.AddComponent<InputEventComponent>().enabled=false;
            GameObject.DontDestroyOnLoad(_scene);

            _root = new GameObject(CommonConstants.ROOT_NAME);
            _root.tag = CommonConstants.ROOT_TAG;
            _root.AddComponent<BaseBehaviour>();
            GameObject.DontDestroyOnLoad(_root);
            _scene.transform.parent = _root.transform;
        }
        public static SceneManager getInstance()
        {
            if (instance == null)
            {
                instance = new SceneManager();
                _cacheService = (CacheService)CEventDriven.getInstance().getService(typeof(CacheService).Name);

            }
            return instance;
        }
        #region interaction with UI
        public void disableUI(string which)
        {
            if (which.Equals(UI_CONSTANT.UI_LOGIN))
            {

                try
                {
                    NGUITools.SetActive(GameObject.Find(which), false);
                }
                catch (System.Exception ex)
                {
                    throw new System.Exception("Occur a error when close " + which.ToUpper() + " screen" + ".Error details:" + ex.Message);
                }
            }
        }

        #endregion

        #region interaction with player


    /*    public void setEnableInput(bool toggle)
        {
            isInput = toggle;


        }
        public void enablecollectInputEvent()
        {
            setEnableInput(true);
            DebugTool.Log("_scene" + _scene);
            _scene.GetComponent<MonoBehaviour>().StartCoroutine(collectInputEvent());

        }*/

       /* public IEnumerator collectInputEvent()
        {
            DebugTool.Log("Enable Mouse Input action");
            while (isInput)
            {
                if (Input.GetMouseButton(0))
                {
                    currMousePos = Input.mousePosition;
                    currMousePos = Camera.main.ScreenToWorldPoint(currMousePos);
                    BaseModel m = new CharacterProfile.BaseValueModel();
                    m.type = Character.Character.HERO_KING;
                    list.Enqueue(new SceneManager.CharacterDataModel().addBaseModel(m).addParent(_root.transform).setPosition(currMousePos));
                    yield return new WaitForSeconds(Random.Range(0, 9) / 10f + 0.5f);
                }
            }
        }*/

     /*   IEnumerator actionInput()
        {
            while (isInput)
            {
                if (list.Count > 0)
                {
                    instanceCharacter(list.Dequeue(), new Vector3(1, 1, 1), Quaternion.identity);
                }
                yield return null;
            }
        }*/
        public class CharacterDataModel
        {
            public BaseModel _base;
            public Transform _parent;
            public Vector3 _pos;
            public CharacterDataModel addBaseModel(BaseModel b)
            {
                if (b != null)
                    _base = b;
                return this;
            }
            public CharacterDataModel addParent(Transform parent)
            {
                if (parent != null)
                    _parent = parent;
                return this;
            }
            public CharacterDataModel setPosition(Vector3 pos)
            {
                if (pos != null)
                    _pos = pos;
                return this;
            }
        }
        public void instanceCharacter(CharacterDataModel model, Vector3 scale, Quaternion rotation)
        {
            UnityEngine.Debug.Log(CEventDriven.getInstance().getService(typeof(CacheService).Name));
            //find a appropriate one
            string type = "";
            if (model._base != null)
                switch (model._base.type)
                {
                    case Character.Character.HERO_KING:
                        findInstanceFromCache(type, model._parent, model._pos, scale, rotation);
                        break; ;

                }
        }
        public void predefinePrefabs()
        {
            var item = UnityEngine.Object.Instantiate(Resources.Load(Characters.Resource.Path.MAP_TILE)) as GameObject;
            var copy = UnityEngine.Object.Instantiate(Resources.Load(Characters.Resource.Path.ARCHER)) as GameObject;
            var copy2 = UnityEngine.Object.Instantiate(Resources.Load(Characters.Resource.Path.HEALTH_BAR)) as GameObject;

            int d = 5;
            while (d > 0)
            {
                putDefaultObjectTOPool(Characters.ARCHER, UnityEngine.Object.Instantiate(copy) as GameObject);
                putDefaultObjectTOPool(Characters.MAP_TILE, UnityEngine.Object.Instantiate(item) as GameObject);
                putDefaultObjectTOPool(Characters.Component.HEALTH_BAR, copy2);

                d--;
            }



        }
        private void putDefaultObjectTOPool(String type, GameObject go)
        {

            _cacheService._cacheManager.prefabPool.addPrefab(type, go.transform);

        }
        private GameObject findInstanceFromCache(string type, Transform parent, Vector3 pos, Vector3 scale, Quaternion rotation)
        {

            return _cacheService.spawnGameObject(type, parent, pos, scale, rotation);
        }
        private void rebuildCharacerValues()
        {

        }
        #endregion
        public void exit()
        {
            closeAndDistroyBuildInGameObject();
        }
        public void closeAndDistroyBuildInGameObject()
        {

        }

    }
}